函數(function)是一段可重複使用的代碼,主要執行特定的任務或計算,並可以選擇返回一個值,主要分成以下幾種:
function greet(name) {
console.log(`hihi~${name}`); // "hihi~kuku"
}
greet("kuku");
const greet = function (name) {
console.log(`hihi~${name}`); // "hihi~kuku"
};
greet("kuku");
const greet = (name) => console.log(`hihi~${name}`); // "hihi~kuku"
greet("kuku");
((name) => console.log(`hihi~${name}`))("kuku"); // "hihi~kuku"
map()
、filter()
、reduce()
const newArray = [1, 2, 3].map((val) => val * 2); // [2,4,6]
console.log(newArray);
new
關鍵字來調用。(建構子函數規劃在第 16 天分享)
// 建構函式定義
function Person(name, age = 18) {
this.name = name;
this.age = age;
}
// 使用建構函式創建對象實例
const kuku = new Person("kuku");
console.log(`名字:${kuku.name}; 年齡:${kuku.age}`); // "名字:kuku; 年齡:18"
函式宣告
函式宣告是一種定義函數的方式,使用 function
關鍵字來定義函數,而且這種方式可以在函數定義之前被調用,因為有 hosting。
console.log(sum(1, 2)); // 3
function sum(x, y) {
return x + y;
}
函式表達式(Function Expression)
把函式定義為表達式,通常是把匿名函式
賦值給變數,因為要執行
才會賦值,所以這種宣告方式的函式內容不會在函數定義之前就可以調用。
console.log(result); // Uncaught SyntaxError: Identifier 'result' has already been declared
const result = function (x, y) {
return x + y;
};
🔔 提升(hosting):
變數提升:
用var
宣告的變數被提升到其作用域的頂部,並用undefined
進行初始化
console.log(imVar); // undefined
var imVar = 6;
console.log(imVar); // 6
let
和const
宣告的變數被提升,但在TDZ(臨時死區)
中保持未初始化狀態,直到到達其宣告為止
console.log(imConst); // Uncaught ReferenceError: Cannot access 'imVar' before initialization
const imConst = 6;
console.log(imConst); // 6
函數提升: 函數宣告完全提升,而函數表達式則不以相同的方式提升
console.log(sum(1, 2)); // 3
function sum(x, y) {
return x + y;
}
箭頭函數是 ES6 引入的一種函數定義方式,語法更簡潔。
箭頭函式的 6 種 return
const greet = () => "hello~";
console.log(greet()); // hello~
const square = x => x * x;
console.log(square(2)); // 4
const add = (a, b) => a + b;
console.log(add(2, 3)); // 5
{}
後在裡面使用 return
const greetSomeone = name => {
return `hello~, ${name}`;
}
console.log(greetSomeone(kuku)); // hello~, kuku
const getProductDetail = (product, number) => ({ product, number })
console.log(getProductDetail(apple, 6)); // { product: 'apple', number: 6 }
const numberList = [1, 2, 3, 4];
const square = numberList.map(num => num * num);
console.log(square(2)); // [1, 4, 9, 16]
⚠️ 語法變簡單,但是要注意:
ES6 創造箭頭函數就是用來解決傳統函數中的this
綁定問題,所以箭頭函數沒有
自己的this
,它們是從父層作用域繼承這些值的。
(關於this
這件事規劃在第 17 天分享)
greet
在箭頭函數內,this
指的是父作用域
const greet = () => console.log(this); // Window
greet();
JavaScript 是
物件導向設計
的語法,this
往外指沒有物件,就會回到最初存在的地方window
。
greet
物件內包一個函式 hi()
而且用函式表達式,函數中的 this.name
指的是 greet
物件
const greet = {
name: "kuku",
sayHi() {
const hi = () => console.log(this.name); //kuku
hi();
}
};
greet.sayHi();
函數作用域(Function Scope)
函數作用域指的是變數在函數內部的可見範圍,只要在函數內部聲明一個變數時,這個變數只在該函數內部有效,這種作用域有助於避免變數命名衝突。
function example() {
var localVar = 'I am local'; // 在這裡定義的變數只在函數內有效
console.log(localVar); // Output: I am local
}
example();
console.log(localVar); // ReferenceError: localVar is not defined
閉包(Closures)
當一個函數在另一個函數中定義時,就會發生閉包,即使在外部函數完成執行之後,內部函數也可以存取外部函數的變數,closureFunction
保留對 outerVariable
的存取。
🔔 簡單來說,閉包就是內層函式可以取得外層函式作用域的變數。
(閉包與作用域規劃在第 18 天分享)
// closureExample 是一個函數工廠,創建和返回了一個閉包
function closureExample() {
const outerVariable = "我只存活在 closureExample 中"; // outerVariable 是 closureExample 函數的局部變數
return function () { // 返回一個函數,這個函數是閉包
console.log(outerVariable); // "我只存活在 closureExample 中"
};
}
// closureFun 是一個閉包的實例
const closureFun = closureExample();
closureFun();